package com.jfinal.ext.ueditor.entity;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.ext.util.file.FileHash;
import com.jfinal.ext.util.rand.MyUuidUtil;
import com.jfinal.kit.FileKit;
import com.jfinal.log.Log;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author 江理_网猿 (timor)
 * date: 2020-9-10
 */
public class FileInfo {
    private static final Log LOG = Log.getLog(FileInfo.class);

    private static final String MD5 = "md5";
    private static final String SHA1 = "sha1";
    private static final String SHA256 = "sha256";
    private static final String SHA512 = "sha512";

    private static final String EXT_IMAGE_SIZE = "size";
    private static final String IMAGE_SIZE_ORIGINAL = "original";


    private String id;
    private String type;
    private String newName;
    private String originalName;
    private String extension;
    private long length;
    private String url;
    private JSONObject ext = new JSONObject();
    private final Set<FileHash> hashFunc;
    private final Map<String, String> hash = new HashMap<>();

    public FileInfo() {
        this(Set.of(FileHash.MD5, FileHash.SHA1, FileHash.SHA256));
    }

    public FileInfo(@NotNull Set<FileHash> hashFunc) {
        this.hashFunc = hashFunc;
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    public static FileInfo by(@NotNull File file, @NotNull String type) {
        final FileInfo fileInfo = by(file);

        fileInfo.setType(type);

        return fileInfo;
    }

    public static FileInfo by(@NotNull File file) {
        final FileInfo fileInfo = new FileInfo();

        final String id = MyUuidUtil.get();
        final String extension = FileKit.getFileExtension(file);
        final String newName = id + "." + extension;

        fileInfo.setId(id);
        fileInfo.setNewName(newName);
        fileInfo.setOriginalName(file.getName());
        fileInfo.setExtension(extension);
        fileInfo.setFileAttr(file);

        return fileInfo;
    }

    public void setFileAttr(@NotNull File file) {
        setLength(file.length());

        hashFunc.forEach(fileHash -> {
            try {
                hash.put(fileHash.getAlgorithm(), fileHash.hash(file));
            } catch (IOException e) {
                LOG.warn("获取hash失败!", e);
            }
        });
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    public String getMd5() {
        return hash.get(MD5);
    }

    public void setMd5(String md5) {
        hash.put(MD5, md5);
    }


    public String getSha1() {
        return hash.get(SHA1);
    }

    public void setSha1(String sha1) {
        hash.put(SHA1, sha1);
    }


    public String getSha256() {
        return hash.get(SHA256);
    }

    public void setSha256(String sha256) {
        hash.put(SHA256, sha256);
    }


    public String getSha512() {
        return hash.get(SHA512);
    }

    public void setSha512(String sha512) {
        hash.put(SHA512, sha512);
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    public String getImageSize() {
        return ext.getString(EXT_IMAGE_SIZE);
    }

    public void setImageSize(String size) {
        ext.put(EXT_IMAGE_SIZE, size);
    }

    public void setOriginalSize() {
        ext.put(EXT_IMAGE_SIZE, IMAGE_SIZE_ORIGINAL);
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getNewName() {
        return newName;
    }

    public void setNewName(String name) {
        this.newName = name;
    }

    public String getOriginalName() {
        return originalName;
    }

    public void setOriginalName(String originalName) {
        this.originalName = originalName;
    }

    public String getExtension() {
        return extension;
    }

    public void setExtension(String extension) {
        this.extension = extension;
    }

    public long getLength() {
        return length;
    }

    public void setLength(long length) {
        this.length = length;
    }

    public JSONObject getExt() {
        return ext;
    }

    public void setExt(JSONObject ext) {
        this.ext = ext;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

}
